import React, {Component} from 'react';
import PropTypes from 'prop-types'

let {
    // string,
    // node,
    // element,
    // instanceOf,
    // oneOf,
    // number,
    // oneOfType,
    // arrayOf,
    // objectOf,
    // shape,
} = PropTypes

// instanceOf 验证
// class BBB extends Component {
//     render() {
//         return (
//             <div>bbb</div>
//         )
//     }
// }
// class AAA extends Component {
//     render() {
//         return (
//             <div>aaa</div>
//         )
//     }
// }
// const aaa = new AAA()

// 创建类组件
class Child extends Component {
    // 属性类型验证
    static propTypes = {
        // title: string
        // title: node
        // title: element
        // title: instanceOf(BBB)
        // title: oneOf(['hello','world'])
        // title: oneOfType([
        //     string,
        //     number
        // ])
        // title: arrayOf(string)
        // title: objectOf(string)
        // title: shape({
        //     name: string.isRequired,  // isRequired：必填，其他是选填
        //     age: number,
        //     gender: string
        // })

        // 自定义验证
        title(props,propName,componentName){
            if(props.title.name === "最爱吃兽奶"){

            } else {
                return new Error()
            }
        }

    }

    render() {
        // console.log(this.props.title)
        return (
            // <div>child {this.props.title}</div>
            // <div>child { this.props.title.x }</div>   // 对象

            <div>child</div>   // instanceOf

        )
    }
}

export default class PropType extends Component {
    render() {
        return (
            <div>
                {/*<Child title="hello"/>*/}
                {/*<Child title={0}/>*/}
                {/*<Child title={['0','1']    /* 数组 *!//>*/}
                {/*<Child title={{x: 0}    /* 对象 *!//>*/}
                {/*<Child title={<div>bbb</div>    /* jsx *!//>*/}
                {/*<Child title={<BBB/>    /* node； 或element: 只能如此；*!//>*/}
                {/*<Child title={aaa    /* instanceOf *!//>*/}
                {/*<Child title={'hello'    /* oneOf *!//>*/}
                {/*<Child title={'hello'    /* oneOfType: 这里可以是string和number类型 *!//>*/}
                {/*<Child title={{a:'hello'}    /* arrayOf: 这里可以是string类型 *!//>*/}
                <Child title={{name:"最爱吃兽奶",age:18,gender:"男"}   /* shape: 需要按设定好的形状传参，一般用作接口 */}/>
            </div>
        );
    }
}


// import React from 'react';
// import PropTypes from 'prop-types';
//
// class MyComponent extends React.Component {
//     render() {
//         // ... do things with the props
//     }
// }
//
// MyComponent.propTypes = {
//     // 你可以声明一个 prop 是一个特定的 JS 原语。
//     // 默认情况下，这些都是可选的。
//     optionalArray: PropTypes.array,
//     optionalBigInt: PropTypes.bigint,
//     optionalBool: PropTypes.bool,
//     optionalFunc: PropTypes.func,
//     optionalNumber: PropTypes.number,
//     optionalObject: PropTypes.object,
//     optionalString: PropTypes.string,
//     optionalSymbol: PropTypes.symbol,
//
//     // 可以呈现的任何内容：数字、字符串、元素或数组
//     //（或片段）包含这些类型。
//     // 请参阅 https://reactjs.org/docs/rendering-elements.html 了解更多信息
//     optionalNode: PropTypes.node,
//
//     // 一个 React 元素（即 <MyComponent />）。
//     optionalElement: PropTypes.element,
//
//     // React 元素类型（例如 MyComponent）。
//     // 一个函数、字符串或“类元素”对象（例如 React.Fragment、Suspense 等）
//     // 参见 https://github.com/facebook/react/blob/HEAD/packages/shared/isValidElementType .js
//     optionalElementType: PropTypes.elementType,
//
//     // 你也可以声明一个 prop 是一个类的实例。这使用 JS 的 instanceof 运算符。
//     optionalMessage: PropTypes.instanceOf(Message),
//
//     // 您可以通过将其视为枚举来确保您的 prop 仅限于特定值
//     optionalEnum: PropTypes.oneOf(['News', 'Photos']),
//
//     // 可以是多种类型之一的对象
//     optionalUnion: PropTypes.oneOfType([
//         PropTypes.string,
//         PropTypes.number,
//         PropTypes.instanceOf(Message)
//     ]),
//
//     // 特定类型的数组
//     optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
//
//     // 具有特定类型属性值的对象
//     optionalObjectOf: PropTypes.objectOf(PropTypes.number),
//
//     // 您可以将上述任何内容与 `isRequired` 链接起来，以确保在未提供 prop 时显示
//
//     // 具有特定形状的对象
//     optionalObjectWithShape: PropTypes.shape({
//         optionalProperty: PropTypes.string,
//         requiredProperty: PropTypes.number.isRequired
//     }),
//
//
//     // 一个对额外属性有警告的对象
//     optionalObjectWithStrictShape: PropTypes.exact({
//         optionalProperty: PropTypes.string,
//         requiredProperty: PropTypes.number.isRequired
//     }),
//
//     requiredFunc: PropTypes.func.isRequired,
//
//     // 任何数据类型的值
//     requiredAny: PropTypes.any.isRequired,
//
//     // 您还可以指定自定义验证器。
//     // 如果验证失败，它应该返回一个错误 对象。不要 `console.warn` 或 throw，因为这在 `oneOfType` 中不起作用。
//     customProp: function (props, propName, componentName) {
//         if (!/matchme/.test(props[propName])) {
//             return new Error(
//                 'Invalid prop `' + propName + '` supplied to' +
//                 ' `' + componentName + '`. Validation failed.'
//             );
//         }
//     },
//
//     // 您还可以为 `arrayOf` 和 `objectOf` 提供自定义验证器。
//     // 如果验证失败，它应该返回一个错误对象。
//     // 将为数组或对象中的每个键调用验证器。验证器的前两个参数是数组或对象本身，或当前项目的键。
//     customArrayProp: PropTypes.arrayOf(function (propValue, key, componentName, location, propFullName) {
//         if (!/matchme/.test(propValue[key])) {
//             return new Error(
//                 'Invalid prop `' + propFullName + '` supplied to' +
//                 ' `' + componentName + '`. Validation failed.'
//             );
//         }
//     })
// };